﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using thinger.AutomaticStoreMotionModels;

namespace thinger.AutomaticStoreMotionDAL
{
    public class GTSMotionEx
    {
        #region 单例模式
        //创建静态字段，保持当前实例
        private static GTSMotionEx _instance;
        //定义一个锁
        private static readonly object _objLocd = new object();
        //创建一个私有的构造函数
        private GTSMotionEx()
        { }

        public static GTSMotionEx GetInstance()
        {
            if (_instance == null)            //第一次判断，可以有效的减少多线程访问时的Lock锁影响的效率问题
            {
                lock (_objLocd)
                {
                    if (_instance == null)    //两次判断，防止两个线程同时进入第一个if里面，一个在Lock外等待，另外一个在Lock内
                    {
                        _instance = new GTSMotionEx();
                    }
                }
            }
            return _instance;
        }
        #endregion

        #region 字段属性
        //创建一个Motion对象
        private Motion _motion = new Motion();

        public BasicParam BasicParam { get { return _motion.basicParam; } }

        public AdvancedParam AdvancedParam { get { return _motion.advancedParam; } }
        #endregion

        #region 基础参数保存
        public OperationResult SaveBasicParam()
        {
            return _motion.SaveBasicParam();
        }
        #endregion

        #region 高级参数保存
        public OperationResult SaveAdvancedParam()
        {
            return _motion.SaveAdvancedParam();
        }
        #endregion

        #region 板卡控制
        /// <summary>
        /// 初始化卡
        /// </summary>
        /// <returns></returns>
        public OperationResult InitCard()
        {
            return _motion.InitCard();
        }

        /// <summary>
        /// 关闭板卡
        /// </summary>
        /// <returns></returns>
        public OperationResult CloseCard()
        {
            return _motion.CloseCard();
        }
        #endregion

        #region 点动控制
        /// <summary>
        /// X轴JOG
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public OperationResult JogMoveAxisX(bool dir)
        {
            return _motion.JogMove(AdvancedParam.nudAxisXNo, dir ? BasicParam.nudAxisXHandSpeed : BasicParam.nudAxisXHandSpeed * -1, AdvancedParam.nudAxisXAcc);
        }

        /// <summary>
        /// Y轴JOG
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public OperationResult JogMoveAxisY(bool dir)
        {
            return _motion.JogMove(AdvancedParam.nudAxisYNo, dir ? BasicParam.nudAxisYHandSpeed : BasicParam.nudAxisYHandSpeed * -1, AdvancedParam.nudAxisYAcc);
        }

        /// <summary>
        /// Z轴JOG
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public OperationResult JogMoveAxisZ(bool dir)
        {
            return _motion.JogMove(AdvancedParam.nudAxisZNo, dir ? BasicParam.nudAxisZHandSpeed : BasicParam.nudAxisZHandSpeed * -1, AdvancedParam.nudAxisZAcc);
        }

        /// <summary>
        /// 根据按钮名称进行轴JOG触发
        /// </summary>
        /// <param name="name">按钮名称</param>
        /// <returns>操作结果</returns>
        public OperationResult JogMoveAxis(string name)
        {
            name = name.ToUpper();
            if (name.StartsWith("X"))
            {
                if (name.EndsWith("+"))
                {
                    return JogMoveAxisX(true);
                }
                else
                {
                    return JogMoveAxisX(false);
                }
            }
            else if (name.StartsWith("Y"))
            {
                if (name.EndsWith("+"))
                {
                    return JogMoveAxisY(true);
                }
                else
                {
                    return JogMoveAxisY(false);
                }
            }
            else if (name.StartsWith("Z"))
            {
                if (name.EndsWith("+"))
                {
                    return JogMoveAxisZ(true);
                }
                else
                {
                    return JogMoveAxisZ(false);
                }
            }
            else
            {
                return new OperationResult()
                {
                    IsSuccess = false,
                    ErrorMsg = "参数名称不正确，没有以XYZ开头"
                };
            }
        }

        /// <summary>
        /// 轴停止
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public OperationResult StopAxis(string name)
        {
            name = name.ToUpper();
            if (name.StartsWith("X"))
            {
                return _motion.StopAxis(AdvancedParam.nudAxisXNo);
            }
            else if (name.StartsWith("Y"))
            {
                return _motion.StopAxis(AdvancedParam.nudAxisYNo);
            }
            else if (name.StartsWith("Z"))
            {
                return _motion.StopAxis(AdvancedParam.nudAxisZNo);
            }
            else
            {
                return new OperationResult() { IsSuccess = false, ErrorMsg = "参数名称不正确，没有以XYZ开头" };
            }
        }
        #endregion

        #region 获取输出
        /// <summary>
        /// 获取所有输出
        /// </summary>
        /// <returns></returns>
        public short GetOutput()
        {
            return _motion.GetOutput();
        }

        /// <summary>
        /// 根据索引获取输出
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public bool GetOutput(short index)
        {
            return _motion.GetOutput(index);
        }

        /// <summary>
        /// 获取系统模式
        /// </summary>
        /// <returns></returns>
        public bool GetModeState()
        {
            return GetOutput(AdvancedParam.nudModeState);
        }
        #endregion

        #region 设置输出
        /// <summary>
        /// 根据索引控制某个位
        /// </summary>
        /// <param name="index"></param>
        /// <param name="open"></param>
        /// <returns></returns>
        public OperationResult SetOutput(int index, bool open)
        {
            return _motion.SetOutput(index, open);
        }

        /// <summary>
        /// 设置存料状态
        /// </summary>
        /// <param name="open"></param>
        /// <returns></returns>
        public OperationResult SetStoreState(bool open)
        {
            return SetOutput(AdvancedParam.nudStoreState, open);
        }

        /// <summary>
        /// 设置模式状态
        /// </summary>
        /// <param name="open"></param>
        /// <returns></returns>
        public OperationResult SetModeState(bool open)
        {
            return SetOutput(AdvancedParam.nudModeState, open);
        }

        /// <summary>
        /// 设置取料状态
        /// </summary>
        /// <param name="open"></param>
        /// <returns></returns>
        public OperationResult SetReclaimState(bool open)
        {
            return SetOutput(AdvancedParam.nudReclaimState, open);
        }

        /// <summary>
        /// 设置气阀
        /// </summary>
        /// <param name="open"></param>
        /// <returns></returns>
        public OperationResult SetClipCtrl(bool open)
        {
            return SetOutput(AdvancedParam.nudClipCtrl, open);
        }
        #endregion

        #region 获取输入
        /// <summary>
        /// 读取所有输入状态
        /// </summary>
        /// <returns></returns>
        public short GetInput()
        {
            return _motion.GetInput();
        }

        /// <summary>
        /// 根据索引读取对应的输入状态
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public bool GetInput(short index)
        {
            return _motion.GetInput(index);
        }

        /// <summary>
        /// 读取存料按钮状态
        /// </summary>
        /// <returns></returns>
        public bool GetStoreButton()
        {
            return GetInput(AdvancedParam.nudStoreState);
        }

        /// <summary>
        /// 读取取料按钮状态
        /// </summary>
        /// <returns></returns>
        public bool GetReclaimButton()
        {
            return GetInput(AdvancedParam.nudReclaimState);
        }
        #endregion

        #region 获取实时位置
        public double GetCmdPosX()
        {
            return _motion.GetCmdPos(AdvancedParam.nudAxisXNo);
        }
        public double GetCmdPosY()
        {
            return _motion.GetCmdPos(AdvancedParam.nudAxisYNo);
        }
        public double GetCmdPosZ()
        {
            return _motion.GetCmdPos(AdvancedParam.nudAxisZNo);
        }
        public string GetCmdPos()
        {
            return GetCmdPosX().ToString("f2") + ";" + GetCmdPosY().ToString("f2") + ";" + GetCmdPosZ().ToString("f2");
        }
        #endregion

        #region XYZ轴绝对定位
        public OperationResult MoveXAbs(double pos)
        {
            return _motion.MoveAbs(AdvancedParam.nudAxisXNo, pos, BasicParam.nudAxisXHandSpeed, AdvancedParam.nudAxisXAcc);
        }
        public OperationResult MoveYAbs(double pos)
        {
            return _motion.MoveAbs(AdvancedParam.nudAxisYNo, pos, BasicParam.nudAxisYHandSpeed, AdvancedParam.nudAxisYAcc);
        }
        public OperationResult MoveZAbs(double pos)
        {
            return _motion.MoveAbs(AdvancedParam.nudAxisZNo, pos, BasicParam.nudAxisZHandSpeed, AdvancedParam.nudAxisZAcc);
        }
        #endregion

        #region XYZ轴清零
        public OperationResult ZeroPos(string name)
        {
            name = name.ToUpper();
            if (name.StartsWith("X"))
            {
                return _motion.ZeroPos(AdvancedParam.nudAxisXNo);
            }
            else if (name.StartsWith("Y"))
            {
                return _motion.ZeroPos(AdvancedParam.nudAxisYNo);
            }
            else if (name.StartsWith("Z"))
            {
                return _motion.ZeroPos(AdvancedParam.nudAxisZNo);
            }
            else
            {
                return new OperationResult()
                {
                    IsSuccess = false,
                    ErrorMsg = "参数名称不正确，没有以XYZ开头"
                };
            }
        }
        #endregion

        #region XYZ轴回原点
        public OperationResult HomeAxis(string name)
        {
            name = name.ToUpper();
            if (name.StartsWith("X"))
            {
                return _motion.HomeAxis(AdvancedParam.nudAxisXNo);
            }
            else if (name.StartsWith("Y"))
            {
                return _motion.HomeAxis(AdvancedParam.nudAxisYNo);
            }
            else if (name.StartsWith("Z"))
            {
                return _motion.HomeAxis(AdvancedParam.nudAxisZNo);
            }
            else
            {
                return new OperationResult()
                {
                    IsSuccess = false,
                    ErrorMsg = "参数名称不正确，没有以XYZ开头"
                };
            }
        }

        public OperationResult HomeAllAxis()
        {
            return _motion.HomeAllAxis();
        }
        #endregion

        #region 自动去称重位
        public OperationResult MoveToWeight(bool isLine = false)
        {
            short[] axis = new short[] { AdvancedParam.nudAxisXNo, AdvancedParam.nudAxisYNo, AdvancedParam.nudAxisZNo };
            double[] pos = new double[] { BasicParam.nudAxisXWeight, BasicParam.nudAxisYWeight, BasicParam.nudAxisZWeight };
            double[] vel = new double[] { BasicParam.nudAxisXAutoSpeed, BasicParam.nudAxisYAutoSpeed, BasicParam.nudAxisZAutoSpeed };
            double[] acc = new double[] { AdvancedParam.nudAxisXAcc, AdvancedParam.nudAxisYAcc, AdvancedParam.nudAxisZAcc };
            if (isLine)
            {
                return _motion.Move3DLineAbs(axis, pos, vel, acc);
            }
            else
            {
                return _motion.Move3DAbs(axis, pos, vel, acc);
            }
        }
        #endregion

        #region 自动去待机位
        public OperationResult MoveToStandby(bool isLine = false)
        {
            short[] axis = new short[] { AdvancedParam.nudAxisXNo, AdvancedParam.nudAxisYNo, AdvancedParam.nudAxisZNo };
            double[] pos = new double[] { BasicParam.nudAxisXStandby, BasicParam.nudAxisYStandby, BasicParam.nudAxisZStandby };
            double[] vel = new double[] { BasicParam.nudAxisXAutoSpeed, BasicParam.nudAxisYAutoSpeed, BasicParam.nudAxisZAutoSpeed };
            double[] acc = new double[] { AdvancedParam.nudAxisXAcc, AdvancedParam.nudAxisYAcc, AdvancedParam.nudAxisZAcc };
            if (isLine)
            {
                return _motion.Move3DLineAbs(axis, pos, vel, acc);
            }
            else
            {
                return _motion.Move3DAbs(axis, pos, vel, acc);
            }
        }
        #endregion

        #region 自动去回收位
        public OperationResult MoveToRecovery(bool isLine = false)
        {
            short[] axis = new short[] { AdvancedParam.nudAxisXNo, AdvancedParam.nudAxisYNo, AdvancedParam.nudAxisZNo };
            double[] pos = new double[] { BasicParam.nudAxisXRecovery, BasicParam.nudAxisYRecovery, BasicParam.nudAxisZRecovery };
            double[] vel = new double[] { BasicParam.nudAxisXAutoSpeed, BasicParam.nudAxisYAutoSpeed, BasicParam.nudAxisZAutoSpeed };
            double[] acc = new double[] { AdvancedParam.nudAxisXAcc, AdvancedParam.nudAxisYAcc, AdvancedParam.nudAxisZAcc };
            if (isLine)
            {
                return _motion.Move3DLineAbs(axis, pos, vel, acc);
            }
            else
            {
                return _motion.Move3DAbs(axis, pos, vel, acc);
            }
        }
        #endregion

        #region 自动去指定的位置
        public OperationResult MoveToPositon(int position, bool isLine = false)
        {
            if (position >= 1 && position <= AdvancedParam.nudRowCount * AdvancedParam.nudColumnCount)
            {
                int row = (position - 1) / AdvancedParam.nudColumnCount;
                int column = (position - 1) % AdvancedParam.nudColumnCount;
                short[] axis = new short[] { AdvancedParam.nudAxisXNo, AdvancedParam.nudAxisYNo, AdvancedParam.nudAxisZNo };
                double[] pos = new double[] { BasicParam.nudAxisXInit + column * BasicParam.nudAxisXOffset, BasicParam.nudAxisYInit + column * BasicParam.nudAxisYOffset, BasicParam.nudAxisZInit };
                double[] vel = new double[] { BasicParam.nudAxisXAutoSpeed, BasicParam.nudAxisYAutoSpeed, BasicParam.nudAxisZAutoSpeed };
                double[] acc = new double[] { AdvancedParam.nudAxisXAcc, AdvancedParam.nudAxisYAcc, AdvancedParam.nudAxisZAcc };
                if (isLine)
                {
                    return _motion.Move3DLineAbs(axis, pos, vel, acc);
                }
                else
                {
                    return _motion.Move3DAbs(axis, pos, vel, acc);
                }
            }
            return new OperationResult() { IsSuccess = false, ErrorMsg = "指定的位置不满足要求" };
        }
        #endregion

    }
}
